﻿#region Using Directives

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using MarketPulse.Reporting.Core.Criteria;

#endregion

namespace MarketPulse.Reporting.Core
{
    /// <summary>
    /// This class represents a set of results for a client, period and reporting level.
    /// </summary>
    public abstract class Results<StorageType> where StorageType : struct
    {
        #region Member Variables

            /// <summary>The unfiltered ReportingVisitInfoList object associated with this Results object.</summary>
            internal ReportingVisitInfoList mReportingVisitList;

        #endregion

        #region Abstract Member Variables

            /// <summary>
            /// Property to hold calculated measures.
            /// </summary>
            protected abstract MeasureCollection<StorageType> mMeasures { get; set; }

        #endregion

        #region Methods

            #region Abstract Methods

                /// <summary>
                /// This method will calculate the scores based on visits in this results object.
                /// </summary>
                public abstract void Calculate();
            
                /// <summary>
                /// This method will retrieve a list of Visits for the given criteria.
                /// </summary>
                /// <param name="criteria">The ResultsCriteria object to retrieve results with.</param>
                internal abstract void FetchVisits(ResultsCriteria criteria);

            #endregion

        #endregion

        #region Properties


            /// <summary>The StartDate for the perspective of our calculation method.</summary>
            public DateTime StartDateTime { get; internal set; }

            /// <summary>The EndDate for the perspective of our calculation method.</summary>
            public DateTime EndDateTime { get; internal set; }

            /// <summary>
            /// Retrieve a measure collection with the given name.
            /// </summary>
            /// <param name="measureName">The name of the measures to retrieve.</param>
            /// <returns>A measure collection containing measures with the given name.</returns>
            public MeasureCollection<StorageType> this[string measureName]
            {
                get
                {
                    return mMeasures.GetByName(measureName);
                }
            }

            /// <summary>
            /// The visits that are current for the given period.
            /// </summary>
            public List<ReportingVisitInfo> CurrentVisits
            {
                get
                {
                    return mReportingVisitList.Where(v => v.RoundStartDateTime >= StartDateTime &&
                                                          v.RoundEndDateTime <= EndDateTime)
                                              .OrderByDescending(v => v.ActualStartDateTime).ToList();
                }
            }


        #endregion
    }
}
